<?php
/**
 * gvisWriter - Google Visualization JavaScript Code Generator
 * depends upon gvis.js (r14 Dec 23, 2008) open source project found at
 * @link http://code.google.com/p/gvis/
 * 
 * 
 * http://code.google.com/p/gviswriter/
 * 
 * @copyright Eric F. Palmer, University of Richmond 2009
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer 
 *   	 in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of Eric F. Palmer, nor the University of Richmond nor the names of its 
 *       contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * @author Eric F. Palmer <Eric@EricFPalmer.com>
 * @author Eric F. Palmer <epalmer.richmond.edu>
 * 
 * @version 0.6.4b
 * 
 * @todo implement all package (chart) typles shown below
 * @todo add basic error handling - assumes only good values are passed in right now
 * @todo add functionaility to support all gvis.js funcionality
 * @todo make __construct__ parameters work as default
 * @todo remove $chartNum passed in and let class take care of that 
 * @todo allow for value formats to be passed in.
 */

/*
 * possible package types
 * 
 * table             // IMPLEMENTED without yet enabling formatted numeric values 
 * piechart          // IMPLEMENTED
 * barchart          // IMPLEMENTED
 * columnchart       // IMPLEMENTED
 * areachart         // IMPLEMENTED
 * linechart         // IMPLEMENTED
 * scatterchart      // IMPLEMENTED
 * imagesparkline    // IMPLEMENTED
 * intensitymap      // IMPLEMENTED
 * geomap            // IMPLEMENTED
 * 
 * When setting a boolean col value to true or false use all LOWERCASE "true" and "false", if need to pass a literal col value
 * use UPPERCASE "TRUE" or "FALSE"
 * 
 * 
 */

class gvisWriter {
	private $chartNum           = null;  // the chartNumber in the page - must be distinct
	private $chartPackageType   = '';    // valid google visualization chart types e.g., 'piechart'
	private $scriptString       = '';    // the JavaScript
	private $chartDivName       = '';
	private $tableProperties    = '';
	private $chartWidth         = 0;
	private $chartHeight        = 0;
	private $rowStringArray     = array();	
	private $colStringArray     = array();
	/**
	 * Allows users to insert arbirary code into the generated JS draw function just before the chart.draw command.
	 *
	 * @var unknown_type
	 */
	private $jsUserInsertedDrawCode = ''; 
	
	function __construct($chartNum, $chartPackageType, $chartDivName, $tableProperties, $jsUserInsertedDrawCode = '') {
		$this->chartNum                 = $chartNum;
		$this->chartPackageType         = $chartPackageType;
		$this->chartDivName             = $chartDivName;		
		$this->tableProperties          = $tableProperties;
		$this->jsUserInsertedDrawCode  = $jsUserInsertedDrawCode;
	}
	/**
	 * @return string
	 */
	private function getRowSetString(){
		$returnString =  '['.implode(', ' , $this->rowStringArray) .']';
		//echo $returnString ."<br/>\n";
		return $returnString;
	}
	private function getColSetString(){
		$returnString =  '{'.implode(', ' , $this->colStringArray) .'}';
		//echo $returnString ."<br/>\n";
		return $returnString;
	}	
	/**
	 * @return void
	 */
	public function addColType ($colValuesArray) {
		$tempColValuesArray = array();
		foreach ($colValuesArray as $value) {
			if (is_string($value)==TRUE ) {
				$value = '"'.$value.'"';
			}
			$tempColValuesArray[] = $value; 
		}
		$colString = implode(': ',$tempColValuesArray);
		//echo $rowString ."<br/>\n";
		// must pass true and false without quotes as a column value 
		
		$this->colStringArray[] = $colString;
	}	
	/**
	 * @return void
	 */
	public function addRow ($rowValuesArray) {
		$tempRowValuesArray = array();
		foreach ($rowValuesArray as $value) {
			if (is_string($value)==TRUE ) {
				$value = '"'.$value.'"';
			}
			$tempRowValuesArray[] = $value; 
		}
		$rowString = '['. implode(', ',$tempRowValuesArray) . ']';
		//echo $rowString ."<br/>\n";
		
		$this->rowStringArray[] = str_replace('"false"', 'false', str_replace('"true"', 'true', $rowString));
	}
/**
	 * @return string
	 */
	public function getScriptString () {
		$scriptString  = '';
		$scriptString .= "<script type=\"text/javascript\">\n";
        $scriptString .= "   google.load(\"visualization\", \"1\", {packages:[\"{$this->chartPackageType}\"]});\n";
        $scriptString .= "   google.setOnLoadCallback(drawChart);\n";
        $scriptString .= "   function drawChart() {\n";
        $scriptString .= "     var chart{$this->chartNum} = new GVis(\"{$this->chartDivName}\", \"{$this->chartPackageType}\");\n";
        if (strlen($this->getColSetString()) >0) {
        	$scriptString .= "      chart{$this->chartNum}.addColumns({$this->getColSetString()}); \n"; 	
        }
		$scriptString .= "      chart{$this->chartNum}.setRows({$this->getRowSetString()}); \n"; 
// @todo add function to setFormattedValue
// @todo add function to call any arbitrary Google Visulaization native function 
/* note theis is done $gvisObject.data.function - see below */
		//$scriptString .= "      chart{$this->chartNum}.data.setFormattedValue(0,2,'blah'); \n";  // this one
		

		if (strlen($this->jsUserInsertedDrawCode) >0) {
        	$scriptString .= "      ".$this->jsUserInsertedDrawCode . " \n"; 	
        }
		
       	$scriptString .= "      chart{$this->chartNum}.draw({ {$this->tableProperties} });\n ";
        $scriptString .= "   }\n";
        $scriptString .= "</script>\n";              
		return $scriptString; 
	}	
}

